#include "daemon_sub_process.h"
#include <stdlib.h>
#include <unistd.h>
#include "log/log.h"
#include "sys/types.h"
#include "sys/wait.h"
#include "sys/reboot.h"
#include <signal.h>

//初始化一个进程
SubProcess *daemon_sub_process_init(char *cmd_param){
    SubProcess * sp=(SubProcess *)malloc(sizeof(SubProcess));
    sp->cmd_param=cmd_param;
    sp->fail_count=0;
    sp->pid=-1;

    return sp;
}

//检查进程是否正在运行子进程程序（没启动启动，启动的不启动）
int daemon_sub_process_checkStart(SubProcess *sp){
    int status=0;
    //无须启动的情况
    //1.先判断是否正在运行(pid大于0说明是子进程，wait非阻塞模式返回0说明在执行)
    if(sp->pid>0&&waitpid(sp->pid,&status,WNOHANG)==0){
        log_debug("子进程正在运行");
        return 0;
    }
    //2.判断是否启动失败（wait第二参数返回0表示执行成功）
    if(status!=0){
        sp->fail_count++;
        if(sp->fail_count>MAX_FAIL_COUNT){
            //重启
            reboot(RB_AUTOBOOT);
        }
    }
    //前面俩判断的是无需启动，接下来是需要启动
    //// 启动  (没有启动过/已经结束了)
    sp->pid=fork();
    //判断是否为子进程，若是则启动对应程序
    if(sp->pid==0){
        //mian函数俩参数分别为程序路径和功能参数(app/ota),NULL表示结束
        char  *argv[]={EXE_PATH,sp->cmd_param,NULL};
        //清空进程空间，并且用该子进程切换执行另一函数
        execv(EXE_PATH,argv);
        //执行到这说明子进程切换失败了，退出子进程
        log_error("找不到对应的程序执行，结束当前程序");
        _exit(EXIT_FAILURE);
    }
    else if(sp->pid<0){
        log_error("创建子进程失败");
        return -1;
    }
    return 0;
}

//销毁一个进程
int daemon_sub_process_destroy(SubProcess *sp){
    //杀死子进程,同时释放信号量
    kill(sp->pid,SIGTERM);
    //等待子进程结束
    waitpid(sp->pid,NULL,0);
    //释放内存
    free(sp);
    return 0;
}
